package com.lg.shiro;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.lg.mapper.PermissionMapper;
import com.lg.mapper.RoleMapper;
import com.lg.mapper.RolePermissionMapper;
import com.lg.mapper.UserMapper;
import com.lg.mapper.UserRoleMapper;
import com.lg.pojo.Permission;
import com.lg.pojo.Role;
import com.lg.pojo.RolePermission;
import com.lg.pojo.RolePermissionExample;
import com.lg.pojo.User;
import com.lg.pojo.UserExample;
import com.lg.pojo.UserRole;
import com.lg.pojo.UserRoleExample;
import com.lg.service.UserService;
@Repository
public class CustomeRealm extends AuthorizingRealm {

	@Autowired
	private UserMapper userMapper;
	@Autowired
	private UserRoleMapper userRoleMapper;
	@Autowired
	private RolePermissionMapper rolePermissionMapper;
	@Autowired
	private PermissionMapper permissionMapper;
	@Autowired
	private RoleMapper roleMapper;
	@Autowired
	private UserService userService;
    public String getName() {
        return "customeRealm";
    }
	@Override
	@Autowired
	@Qualifier("credentialsMatcher")
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		// TODO Auto-generated method stub
		super.setCredentialsMatcher(credentialsMatcher);
	}
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		  //null usernames are invalid
        if (principals == null) {
            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
        }
		   Set<String> roleNames = new HashSet<>();
	        Set<String> permissions =  new HashSet<>();
		User user = (User) principals.getPrimaryPrincipal();
		UserRoleExample example = new UserRoleExample();
		example.createCriteria().andUidEqualTo(user.getUid());
		List<UserRole> userRoles = userRoleMapper.selectByExample(example );
		for (UserRole userRole : userRoles) {
			Role selectByPrimaryKey2 = roleMapper.selectByPrimaryKey(userRole.getRoleId());
			roleNames.add(selectByPrimaryKey2.getRole());
			RolePermissionExample rolePermissionExample = new  RolePermissionExample();
			rolePermissionExample.createCriteria().andRoleIdNotEqualTo(userRole.getRoleId());
			List<RolePermission> selectByExample = rolePermissionMapper.selectByExample(rolePermissionExample);
			for (RolePermission rolePermission : selectByExample) {
				Permission selectByPrimaryKey = permissionMapper.selectByPrimaryKey(rolePermission.getPermissionId());
				permissions.add(selectByPrimaryKey.getPermission());
			}
		}
	    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
        info.setStringPermissions(permissions);
        return info;

	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// TODO Auto-generated method stub
		String principal = (String)token.getPrincipal();
		UserExample example = new UserExample();
		example.createCriteria().andUsernameEqualTo(principal);
		List<User> selectByExample = userMapper.selectByExample(example );
		if(selectByExample != null && !selectByExample.isEmpty()) {
			User user = selectByExample.get(0);
			SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
		
		  return simpleAuthenticationInfo;
		}
		return null;
	}

}
